﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;      
using System.Text;
using System.Windows.Forms;
using EnvDTE;
using RuleCode.ObjectTree;
using System.IO;
using System.Xml;
using Ionic.Zip;
using VSLangProj80;

namespace VSObjectTreeAddIn
{
    public partial class NewSharpERPSolution : Form
    {

        /// <summary>
        /// 获取或设置当前数据库连接字符串的ID
        /// </summary>
        protected string ConnectStringID
        {
            get;
            set;
        }

        /// <summary>
        /// 获取或设置 插件对象
        /// </summary>
        public DTE AddIn_ApplicationObject
        {
            get;
            set;
        }

        public NewSharpERPSolution()
        {
            InitializeComponent();
        }

        #region 初始化
        protected void InitData()
        {
            RadioButton_BS.Checked = true;
            RadioButton_CS.Checked = false;
        }
        #endregion

        #region 事件
        private void RadioButton_BS_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton_CS.Checked = !RadioButton_BS.Checked;
        }

        private void RadioButton_CS_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton_BS.Checked = !RadioButton_CS.Checked;
        }
        #endregion 

        #region 窗体加载
        private void NewSharpERPSolution_Load(object sender, EventArgs e)
        {              
            InitData();
        }
        #endregion

        private void Button_SelectPath_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            if (!String.IsNullOrEmpty(folderBrowserDialog1.SelectedPath))
            {
                TextBox_SolutionPath.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void Button_OK_Click(object sender, EventArgs e)
        {
            if (AddIn_ApplicationObject == null )
            {
                MessageBox.Show("没有加载插件！");
                return;
            }

            if (String.IsNullOrEmpty(TextBox_ProjectForm.Text))
            {
                MessageBox.Show("表现层项目名称不能为空！");
                return;
            }
            if (String.IsNullOrEmpty(this.TextBox_ProjectName_DB  .Text))
            {
                MessageBox.Show("数据层项目名称不能为空！");
                return;
            }
            if (String.IsNullOrEmpty(this.TextBox_SolutionName .Text))
            {
                MessageBox.Show("解决方案名称不能为空！");
                return;
            }
            if (String.IsNullOrEmpty(this.TextBox_SolutionPath .Text) || !Directory .Exists (TextBox_SolutionPath .Text ))
            {
                MessageBox.Show("解决方案路径不能为空，且一定要存在！");
                return;
            }

            if (String.IsNullOrEmpty(TextBox_CNNStr.Text))
            {
                MessageBox.Show("数据库连接不能为空！");
                return;
            }
            if (String.IsNullOrEmpty(TextBox_ConfigName.Text))
            {
                MessageBox.Show("配置名称不能为空！");
                return;
            }

            string newSolutionPath = TextBox_SolutionPath.Text.Trim();
            string newSolutionName = TextBox_SolutionName.Text.Trim();
            string dataProjectName = TextBox_ProjectName_DB.Text.Trim();
            string formProjectName = TextBox_ProjectForm.Text.Trim();

            newSolutionPath = Path.Combine(newSolutionPath, newSolutionName);
            if (!Directory.Exists(newSolutionPath))
                Directory.CreateDirectory(newSolutionPath);

            string solutionTemplatePath = Path.Combine(Util_DTE.AddIn_SetUpPath, "Templates\\Solutions");
            string bsSolutionTemplateName = Path.Combine(solutionTemplatePath, "BS.solutionTemplate");
            string csSolutionTemplateName = Path.Combine(solutionTemplatePath, "CS.solutionTemplate");
            if (Directory.Exists(solutionTemplatePath) )
            {
                string templateFileName = string.Empty;
                if (RadioButton_BS.Checked)
                {
                    if (File.Exists(bsSolutionTemplateName)) 
                        templateFileName = bsSolutionTemplateName; 
                }
                else if (RadioButton_CS.Checked)
                {
                    if (File.Exists(csSolutionTemplateName))
                        templateFileName = csSolutionTemplateName;
                }

                if (templateFileName != string.Empty)
                {
                    XmlDocument templDoc = new XmlDocument();
                    templDoc.Load(templateFileName);
                    XmlNode dataNode = templDoc.SelectSingleNode("//project[@type='DATA']");
                    XmlNode formNode = templDoc.SelectSingleNode("//project[@type='FORM']");
                    if (dataNode != null && formNode != null)
                    {
                        XmlNode dataPathAttr = dataNode.Attributes.GetNamedItem("path");
                        XmlNode formPathAttr = formNode.Attributes.GetNamedItem("path");
                        if(dataPathAttr !=null &&  formPathAttr!=null)
                        {
                            string dataTempFile = Path.Combine(Util_DTE.AddIn_SetUpPath, dataPathAttr.Value);
                            string formTempFile = Path.Combine(Util_DTE .AddIn_SetUpPath ,formPathAttr .Value );
                            if (File.Exists(dataTempFile) && File.Exists(formTempFile))
                            {
                                try
                                {
                                    //创建新的解决方案
                                    string newSolutionFullName = Path.Combine(newSolutionPath, newSolutionName+".sln");
                                    if (File.Exists(newSolutionFullName))
                                        File.Delete (newSolutionFullName);
                                    AddIn_ApplicationObject.Solution.Create(newSolutionPath, newSolutionName);
                                    try
                                    {
                                        AddIn_ApplicationObject.Solution.SaveAs(newSolutionFullName);
                                    }
                                    catch { }
                                    
                                    //添加数据层项目
                                    AddIn_ApplicationObject.Solution.AddFromTemplate(dataTempFile,Path.Combine ( newSolutionPath,dataProjectName ), dataProjectName, false);
                                    Project dataProject = AddIn_ApplicationObject.Solution.Projects.Item(1);

                                    string ruleCodeCommonDllFileName = Path.Combine(Util_DTE.AddIn_SetUpPath ,"RuleCode.Common.dll");
                                    string ruleCodeObjectTreeFileName = Path.Combine(Util_DTE.AddIn_SetUpPath, "RuleCode.ObjectTree.dll");
                                    VSProject2 vsDataProject2 = dataProject.Object as VSProject2;
                                    if (vsDataProject2 != null)
                                    {
                                        try
                                        {
                                            //添加引用
                                            if (File.Exists(ruleCodeCommonDllFileName))
                                                vsDataProject2.References.Add(ruleCodeCommonDllFileName);
                                            if (File.Exists(ruleCodeObjectTreeFileName))
                                                vsDataProject2.References.Add(ruleCodeObjectTreeFileName);
                                        }
                                        catch { }
                                    }

                                    dataProject.SaveAs(dataProject.FullName);
 
                                    //添加表现层项目                           
                                    try
                                    {
                                        XmlDocument formtemplDoc = new XmlDocument();
                                        formtemplDoc.Load(formTempFile);
                                        XmlNamespaceManager namespaceManager = new XmlNamespaceManager(formtemplDoc.NameTable);
                                        namespaceManager.AddNamespace("DD", "http://schemas.microsoft.com/developer/vstemplate/2005");
                                        XmlNode dataLevelParamNode = formtemplDoc.SelectSingleNode("//DD:CustomParameters/DD:CustomParameter[@Name='$DataLevel$']",namespaceManager );
                                        if (dataLevelParamNode != null)
                                        {
                                            dataLevelParamNode.Attributes.GetNamedItem("Value").Value = dataProjectName;   
                                            formtemplDoc.Save(formTempFile);
                                        }


                                        AddIn_ApplicationObject.Solution.AddFromTemplate(formTempFile, Path.Combine(newSolutionPath, formProjectName), formProjectName, false);
                                        Project formProject = AddIn_ApplicationObject.Solution.Projects.Item(2);

                                        string ajaxProFileName = Path.Combine(Util_DTE.AddIn_SetUpPath, "AjaxPro.2.dll");
                                        string webControlsFileName = Path.Combine(Util_DTE.AddIn_SetUpPath, "RuleCode.WebControls.dll");
                                        VSProject2 vsFormProject2 = formProject.Object as VSProject2;
                                        if (vsFormProject2 != null)
                                        {
                                            try
                                            {
                                                //添加项目引用
                                                vsFormProject2.References.AddProject(dataProject);
                                                //添加引用
                                                if (File.Exists(ruleCodeCommonDllFileName))
                                                    vsFormProject2.References.Add(ruleCodeCommonDllFileName);
                                                if (File.Exists(ruleCodeObjectTreeFileName))
                                                    vsFormProject2.References.Add(ruleCodeObjectTreeFileName);
                                                if (File.Exists(ajaxProFileName))
                                                    vsFormProject2.References.Add(ajaxProFileName);
                                                if (File.Exists(webControlsFileName))
                                                    vsFormProject2.References.Add(webControlsFileName);
                                            }
                                            catch { }
                                        }
                                        formProject.SaveAs(formProject.FullName);
                                        if (dataLevelParamNode != null)
                                        {
                                            dataLevelParamNode.Attributes.GetNamedItem("Value").Value = "RuleCode";
                                            formtemplDoc.Save(formTempFile);
                                        }
                                    }
                                    catch { }                              

                                    

                                    //如果要新建所有的基本表的话，则解压对象树文件
                                    if (CheckBox_GenerateTables.Checked)
                                    {
                                        string aotPath = Util.GetUserDataPath() + GlobalStaticDirectoryPath.AOTSProfilePath;
                                        if (!Directory.Exists(aotPath))
                                            Directory.CreateDirectory(aotPath);
                                        string devAreaPath = aotPath + "\\" + newSolutionName;
                                        if (!Directory.Exists(devAreaPath))
                                            Directory.CreateDirectory(devAreaPath);
                                        
                                        string setupDataFilePath = Path.Combine(Util_DTE.AddIn_SetUpPath, "Data");
                                        string sourceAotFileZipFileName = Path.Combine(setupDataFilePath, "DAT.zip");
                                        using (ZipFile labelFileZip = ZipFile.Read(sourceAotFileZipFileName))
                                        {
                                            foreach (ZipEntry entry in labelFileZip)
                                                entry.Extract(devAreaPath, ExtractExistingFileAction.OverwriteSilently);
                                        }
                                    }

                                    //导入模板文件的配置
                                    ImportTemplateConfigure(dataTempFile, dataProjectName, newSolutionName);
                                    ImportTemplateConfigure(formTempFile, formProjectName, newSolutionName);

                                    
                                    //重新初始化配置
                                    Util.SetBack();
                                    Util.InitCurrentProfileName();

                                    AddIn_ApplicationObject.Solution.SaveAs(AddIn_ApplicationObject.Solution.FullName);
                                    //创建配置相关文件
                                    MessageBox.Show("创建成功！");
                                    this.Close();
                                    return;
                                }
                                catch (Exception error)
                                { 
                                }
                            }
                        }
                    }
                }
            }   
  
            //MessageBox.Show("对不起，没有找到相应的项目模板");        
            this.Close();
        }

        private void Button_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Button_SetCNNStr_Click(object sender, EventArgs e)
        {
            DataBaseConfig dataBaseConfig = new DataBaseConfig();
            if (CheckBox_GenerateTables.Checked)
                dataBaseConfig.OnlyNew = true;
            else
                dataBaseConfig.OnlyNew = false;
            dataBaseConfig.ShowDialog();
            string cnnID = dataBaseConfig.ConnectStringID;
            if (!string.IsNullOrEmpty(cnnID))
            {
                ConnectStringID = cnnID;
                string cnnStr = Util.GetConnectString(cnnID);
                this.TextBox_CNNStr .Text = cnnStr;
            }
            else
            {
                this.TextBox_CNNStr.Text = string.Empty;
            }
        }

        protected void ImportTemplateConfigure(string templateFileName, string curProjectName,string defualtConfigName)
        {
            Util.InitCurrentProfileName(); //初始化配置信息
            //string sharpERPPath = Util.GetUserDataPath();
            //string aotsPath = Path.Combine(sharpERPPath, GlobalStaticDirectoryPath.AOTSProfilePath.Trim ("\\".ToCharArray ()));         
            //string configPath = Path.Combine(aotsPath, configname); 
            //if (CheckBox_ImportTempConfig.Checked)
            {
               

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(templateFileName);
                XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
                namespaceManager.AddNamespace("DD", "http://schemas.microsoft.com/developer/vstemplate/2005");
                XmlNode pathsNode = xmlDoc.SelectSingleNode("//DD:config/DD:paths", namespaceManager);
                XmlNode rootnamespaceNode = xmlDoc.SelectSingleNode("//DD:config/DD:RootNameSpace", namespaceManager);

                string solutionName = this.AddIn_ApplicationObject.Solution.FullName;
                XmlDocument solutionsDoc = new XmlDocument();
                solutionsDoc.Load(Util.GetSolutionConfigPath());
                XmlNode solutionNode = solutionsDoc.SelectSingleNode("//solution[@Path='" + solutionName + "']");
                if (solutionNode != null)
                {
                    string ProfileName = string.Empty;
                    XmlNode ProfileNameNode = solutionNode.Attributes.GetNamedItem("ProfileName");
                    if (ProfileNameNode == null || ProfileNameNode.InnerText.Trim() == string.Empty)
                    {
                        if (ProfileNameNode == null)
                        {
                            ProfileNameNode = solutionsDoc.CreateAttribute("ProfileName");
                        }
                        string newProfileName = defualtConfigName;
                        ProfileNameNode.Value = newProfileName;// AddIn_ApplicationObject.Solution.FileName.ToLower().TrimEnd(".sln".ToCharArray());
                        solutionNode.Attributes.Append(ProfileNameNode as XmlAttribute);

                        //在AOTS下创建相应的文件
                        string aotsPath = Path.Combine(Util.GetUserDataPath(), GlobalStaticDirectoryPath.AOTSProfilePath.Trim("\\".ToCharArray()));
                        string profilePath = Path.Combine(aotsPath, newProfileName);
                        if (!Directory.Exists(profilePath))
                            Directory.CreateDirectory(profilePath);
                        string devPath = Path.Combine(profilePath, Util.DevArea);
                        if (!Directory.Exists(devPath))
                            Directory.CreateDirectory(devPath);
                        string setupDataFilePath = Path.Combine(Util_DTE.AddIn_SetUpPath, "Data");

                        //解压代码生成模板
                        string sourceGeneTemplateZipFileName = Path.Combine(setupDataFilePath, "Templates.zip");
                        using (ZipFile geneTemplateZip = ZipFile.Read(sourceGeneTemplateZipFileName))
                        {
                            foreach (ZipEntry entry in geneTemplateZip)
                                entry.Extract(devPath, ExtractExistingFileAction.OverwriteSilently);
                        }
                        //解压LabelFile文件

                        string sourceLabelFileZipFileName = Path.Combine(setupDataFilePath, "LabelFile.zip");
                        using (ZipFile labelFileZip = ZipFile.Read(sourceLabelFileZipFileName))
                        {
                            foreach (ZipEntry entry in labelFileZip)
                                entry.Extract(devPath, ExtractExistingFileAction.OverwriteSilently);
                        }
                    }
                    ProfileName = ProfileNameNode.Value;

                    XmlDocument profilesDoc = new XmlDocument();
                    profilesDoc.Load(Util.GetProfilePath());
                    XmlNode aotsNode = profilesDoc.SelectSingleNode("//aots");
                    XmlNode aotNode = profilesDoc.SelectSingleNode("//aot[@Name='" + ProfileName + "']");
                    if (aotNode == null && aotsNode != null)
                    {
                        aotNode = profilesDoc.CreateElement("aot");
                        XmlAttribute aotNameNode = profilesDoc.CreateAttribute("Name");
                        aotNameNode.Value = ProfileName;
                        aotNode.Attributes.Append(aotNameNode);
                        XmlAttribute cnnStrNode = profilesDoc.CreateAttribute("cnnStringID");
                        cnnStrNode.Value = ConnectStringID;
                        aotNode.Attributes.Append(cnnStrNode);
                        aotNode.Attributes.Append(profilesDoc.CreateAttribute("OTPath_Module"));
                        aotNode.Attributes.Append(profilesDoc.CreateAttribute("OTPath"));
                        aotsNode.AppendChild(aotNode);
                        profilesDoc.Save(Util.GetProfilePath());
                    }

                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:Tables", "//solution[@Path='" + solutionName + "']/paths/Tables", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:Queries", "//solution[@Path='" + solutionName + "']/paths/Queries", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:TableFields", "//solution[@Path='" + solutionName + "']/paths/TableFields", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:ExtendDataTypes", "//solution[@Path='" + solutionName + "']/paths/ExtendDataTypes", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:Enums", "//solution[@Path='" + solutionName + "']/paths/Enums", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:WebForms", "//solution[@Path='" + solutionName + "']/paths/WebForms", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:Classes", "//solution[@Path='" + solutionName + "']/paths/Classes", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:Forms", "//solution[@Path='" + solutionName + "']/paths/Forms", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:LabelFile", "//solution[@Path='" + solutionName + "']/paths/LabelFile", true);
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:config/DD:paths/DD:AOTFile", "//solution[@Path='" + solutionName + "']/paths/AOTFile", true);


                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:RootNameSpace/DD:Classes", "//solution[@Path='" + solutionName + "']/RootNameSpace/Classes", false );
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:RootNameSpace/DD:WebForms", "//solution[@Path='" + solutionName + "']/RootNameSpace/WebForms", false );
                    CopyTemplateNodeInfoToSolutionNode(namespaceManager, curProjectName, xmlDoc, solutionsDoc, "//DD:RootNameSpace/DD:Forms", "//solution[@Path='" + solutionName + "']/RootNameSpace/Forms", false );
                    solutionsDoc.Save(Util.GetSolutionConfigPath());
                }
            }
        }

        protected void CopyTemplateNodeInfoToSolutionNode(XmlNamespaceManager templNamespaceManager, string curProjectName, XmlDocument templateDoc, XmlDocument solutionDoc, string templateNodePath, string solutionNodePath, bool isPath)
        {
            XmlNode templateNode = templateDoc.SelectSingleNode(templateNodePath,templNamespaceManager );
            XmlNode solutionNode = solutionDoc.SelectSingleNode(solutionNodePath);
            if (solutionNode != null && templateNode != null)
            {
                if (isPath)   //Paths 节点
                {
                    XmlNode temProjectAttr = templateNode.Attributes.GetNamedItem("Project");
                    XmlNode solProjectAttr = solutionNode.Attributes.GetNamedItem("Project");
                    if (temProjectAttr != null && solProjectAttr != null)
                    {
                        if (temProjectAttr.Value == "$")
                            solProjectAttr.Value = curProjectName;
                        else
                            solProjectAttr.Value = temProjectAttr.Value;
                    }
                    XmlNode temValueAttr = templateNode.Attributes.GetNamedItem("Value");
                    XmlNode solValueAttr = solutionNode.Attributes.GetNamedItem("Value");
                    if (temValueAttr != null && solValueAttr != null)
                    {
                        solValueAttr.Value = temValueAttr.Value;
                    }
                }
                else     // RootNameSpace 节点
                {
                    if (templateNode.InnerText.Trim() == "$")
                        solutionNode.InnerText = curProjectName;
                    else
                        solutionNode.InnerText = templateNode.InnerText;
                }
            }
        }
        
    }
}
